import {
  Injectable,
  UnauthorizedException,
  BadRequestException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { PrismaService } from '../prisma/prisma.service';
import { VerificationCodeService } from './verification-code.service';
import {
  PhoneLoginDto,
  GoogleLoginDto,
  LoginResponseDto,
  VerificationCodeType,
} from './dto/auth.dto';
import { OAuth2Client } from 'google-auth-library';
import axios from 'axios';

@Injectable()
export class AuthService {
  constructor(
    private prisma: PrismaService,
    private jwtService: JwtService,
    private verificationCodeService: VerificationCodeService,
  ) {}

  /**
   * 手机号验证码登录
   */
  async phoneLogin(loginDto: PhoneLoginDto): Promise<LoginResponseDto> {
    const { phone, code, nickname } = loginDto;

    // 验证验证码
    await this.verificationCodeService.verifyCode(
      phone,
      code,
      VerificationCodeType.LOGIN,
    );

    // 查找或创建用户
    let user = await this.prisma.user.findUnique({
      where: { phone },
    });

    if (!user) {
      // 新用户自动注册
      let finalNickname: string;

      if (nickname) {
        // 如果用户提供了昵称，使用用户提供的昵称
        finalNickname = nickname;

        // 直接创建用户
        user = await this.prisma.user.create({
          data: {
            phone,
            nickname: finalNickname,
            loginType: 'PHONE_CODE',
            phoneVerified: true,
            lastLoginType: 'PHONE_CODE',
            lastLoginAt: new Date(),
            lastLoginIp: '127.0.0.1', // TODO: 获取真实IP
          },
        });
      } else {
        // 如果用户没有提供昵称，先创建用户获取ID，然后生成默认昵称
        user = await this.prisma.user.create({
          data: {
            phone,
            nickname: 'vieNow_temp', // 临时昵称
            loginType: 'PHONE_CODE',
            phoneVerified: true,
            lastLoginType: 'PHONE_CODE',
            lastLoginAt: new Date(),
            lastLoginIp: '127.0.0.1', // TODO: 获取真实IP
          },
        });

        // 生成默认昵称格式
        finalNickname = `vieNow_${user.id}`;

        // 更新昵称为最终格式
        await this.prisma.user.update({
          where: { id: user.id },
          data: { nickname: finalNickname },
        });

        // 更新用户对象
        user.nickname = finalNickname;
      }
    } else {
      // 更新登录信息
      await this.prisma.user.update({
        where: { id: user.id },
        data: {
          loginCount: { increment: 1 },
          lastLoginType: 'PHONE_CODE',
          lastLoginAt: new Date(),
          lastLoginIp: '127.0.0.1', // TODO: 获取真实IP
        },
      });
    }

    // 生成JWT令牌
    const payload = { sub: user.id, phone: user.phone, role: user.role };
    const accessToken = this.jwtService.sign(payload);
    const refreshToken = this.jwtService.sign(payload, { expiresIn: '30d' });

    return {
      accessToken,
      refreshToken,
      user: {
        id: user.id,
        phone: user.phone!,
        nickname: user.nickname,
        avatar: user.avatar || undefined,
        points: user.points,
      },
    };
  }

  /**
   * Google登录
   */
  async googleLogin(loginDto: GoogleLoginDto): Promise<LoginResponseDto> {
    const { idToken } = loginDto;

    try {
      console.log(process.env.NODE_ENV);

      const clientId =
        process.env.NODE_ENV !== 'development'
          ? '82716260351-1co5qnvhctqb4jluo5n537a83o9otadt.apps.googleusercontent.com'
          : '82716260351-eunjm8imnr6pc4djgnoaa9mvdoa08nsh.apps.googleusercontent.com';

      console.log(
        'Token类型:',
        idToken.startsWith('ya29.') ? 'Access Token' : 'ID Token',
      );
      console.log('Client ID:', clientId);

      let googleId: string;
      let email: string;
      let name: string;
      let picture: string;

      if (idToken.startsWith('ya29.')) {
        // 这是Access Token，需要调用Google API获取用户信息
        console.log('使用Access Token获取用户信息...');
        const userInfo = await this.getGoogleUserInfo(idToken);
        googleId = userInfo.id;
        email = userInfo.email;
        name = userInfo.name;
        picture = userInfo.picture;
      } else {
        // 这是ID Token，使用原来的验证方式
        console.log('验证ID Token...');
        const client = new OAuth2Client(clientId);
        const ticket = await client.verifyIdToken({
          idToken,
          audience: clientId,
        });
        console.log('Token验证成功');

        const payload = ticket.getPayload();
        if (!payload) {
          throw new UnauthorizedException('无效的Google Token');
        }

        googleId = payload.sub;
        email = payload.email || '';
        name = payload.name || '';
        picture = payload.picture || '';
      }

      // 查找或创建用户
      let user = await this.prisma.user.findFirst({
        where: {
          OR: [{ googleId }, { email }],
        },
      });

      if (!user) {
        // 新用户自动注册
        let finalNickname: string;

        if (name) {
          // 如果有name，检查昵称是否已存在
          finalNickname = name;
          
          // 检查昵称是否已存在，如果存在则添加后缀
          let counter = 1;
          let uniqueNickname = finalNickname;
          
          while (await this.prisma.user.findUnique({ where: { nickname: uniqueNickname } })) {
            uniqueNickname = `${finalNickname}_${counter}`;
            counter++;
          }
          
          finalNickname = uniqueNickname;
          
          // 创建用户
          user = await this.prisma.user.create({
            data: {
              email,
              nickname: finalNickname,
              loginType: 'GOOGLE',
              lastLoginType: 'GOOGLE',
              lastLoginAt: new Date(),
              lastLoginIp: '127.0.0.1', // TODO: 获取真实IP
              googleId,
              googleEmail: email,
              googleName: name,
              googlePicture: picture,
            },
          });
        } else {
          // 如果没有name，先创建临时用户，然后更新昵称
          const tempUser = await this.prisma.user.create({
            data: {
              email,
              nickname: 'vieNow_temp',
              loginType: 'GOOGLE',
              lastLoginType: 'GOOGLE',
              lastLoginAt: new Date(),
              lastLoginIp: '127.0.0.1', // TODO: 获取真实IP
              googleId,
              googleEmail: email,
              googleName: name,
              googlePicture: picture,
            },
          });

          finalNickname = `vieNow_${tempUser.id}`;

          // 更新昵称为最终格式
          await this.prisma.user.update({
            where: { id: tempUser.id },
            data: { nickname: finalNickname },
          });

          user = tempUser;
          user.nickname = finalNickname;
        }
      } else {
        // 更新用户信息和登录记录
        await this.prisma.user.update({
          where: { id: user.id },
          data: {
            loginCount: { increment: 1 },
            lastLoginType: 'GOOGLE',
            lastLoginAt: new Date(),
            lastLoginIp: '127.0.0.1', // TODO: 获取真实IP
            // 更新Google信息（可能用户重新授权）
            googleId,
            googleEmail: email,
            googleName: name,
            googlePicture: picture,
          },
        });
      }

      // 生成JWT令牌
      const jwtPayload = {
        sub: user.id,
        email: user.email || '',
        role: user.role,
      };
      const accessToken = this.jwtService.sign(jwtPayload);
      const refreshToken = this.jwtService.sign(jwtPayload, {
        expiresIn: '30d',
      });

      return {
        accessToken,
        refreshToken,
        user: {
          id: user.id,
          phone: user.phone || 'google登录',
          nickname: user.nickname,
          avatar: user.googlePicture || user.avatar || undefined,
          points: user.points,
        },
      };
    } catch (error) {
      console.log(error);
      if (error instanceof UnauthorizedException) {
        throw error;
      }
      throw new UnauthorizedException('Google登录失败，请稍后重试');
    }
  }

  /**
   * 刷新令牌
   */
  async refreshToken(refreshToken: string): Promise<{ accessToken: string }> {
    try {
      const payload = this.jwtService.verify(refreshToken);
      const newPayload = {
        sub: payload.sub,
        phone: payload.phone,
        role: payload.role,
      };
      const accessToken = this.jwtService.sign(newPayload);

      return { accessToken };
    } catch (error) {
      throw new UnauthorizedException('无效的刷新令牌');
    }
  }

  /**
   * 验证用户
   */
  async validateUser(userId: number) {
    return this.prisma.user.findUnique({
      where: { id: userId },
    });
  }

  /**
   * 使用Access Token获取Google用户信息
   */
  private async getGoogleUserInfo(accessToken: string) {
    try {
      const response = await axios.get(
        'https://www.googleapis.com/oauth2/v2/userinfo',
        {
          headers: {
            Authorization: `Bearer ${accessToken}`,
          },
        },
      );

      const userData = response.data as any;

      console.log(userData, 'userData');
      return {
        id: userData.id,
        email: userData.email,
        name: userData.name,
        picture: userData.picture,
      };
    } catch (error) {
      console.error('获取Google用户信息失败:', error);
      throw new UnauthorizedException('无法获取Google用户信息');
    }
  }
}
